package com.jfirer.validator.descriptor;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Set;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.ParameterNameProvider;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.ParameterDescriptor;

public class ParameterDescriptorImpl extends CascadableDescriptorImpl implements ParameterDescriptor
{
	protected int		index;
	protected String	name;
	
	public ParameterDescriptorImpl(AccessibleObject accessibleObject, int index, ParameterNameProvider parameterNameProvider, ConstraintValidatorFactory constraintValidatorFactory)
	{
		this.index = index;
		if (accessibleObject instanceof Method)
		{
			Method method = (Method) accessibleObject;
			name = parameterNameProvider.getParameterNames(method).get(index);
			Annotation[] annotations = method.getParameterAnnotations()[index];
			initializeCascadableDescriptor(defineCascaded(annotations), defineGroupConversions(annotations));
			Set<ConstraintDescriptor<?>> descriptors = defineConstraintDescriptors(constraintValidatorFactory, annotations);
			initializeElementDescriptor(method.getParameterTypes()[index], descriptors);
		}
		else if (accessibleObject instanceof Constructor<?>)
		{
			Constructor<?> constructor = (Constructor<?>) accessibleObject;
			name = parameterNameProvider.getParameterNames(constructor).get(index);
			Annotation[] annotations = constructor.getParameterAnnotations()[index];
			initializeCascadableDescriptor(defineCascaded(annotations), defineGroupConversions(annotations));
			Set<ConstraintDescriptor<?>> descriptors = defineConstraintDescriptors(constraintValidatorFactory, annotations);
			initializeElementDescriptor(constructor.getParameterTypes()[index], descriptors);
		}
		else
		{
			throw new IllegalArgumentException();
		}
	}
	
	@Override
	public int getIndex()
	{
		return index;
	}
	
	@Override
	public String getName()
	{
		return name;
	}
	
}
